package cian_f_rice.model;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * The basic model for A1 that contains everything you need for representing
 * a Decision Lines board.
 * <p>
 * Note that you will need to add more logic and functionality here. This skeletal model
 * class is written like this just to get A1.Impl (part I) done.
 * 
 * @author Professor Heineman
 * @author Cian (everything other than skeletal Decision Lines code)
 */
public class DecisionLinesEvent {
	
	/** Expose the number of choices in this decision lines board. */
	public final int numChoices;
	int numRounds;
	
	/**
	 * This is a list of the choices for users to add edges between.
	 */
	
	public ArrayList<Line> lines;
	
	/**
	 * An array list of all edges added to the DLE. Used to check if the DLE is done.
	 */
	
	protected ArrayList<Edge> allEdges;
	
	/**
	 * An array of the prioritized strings to be out put to the console.
	 */
	
	final String[] priorities;
	
	/**
	 * Model at a minimum must know the number of choices, which is chosen to be
	 * passed in as a parameter.
	 * 
	 * @param numChoices
	 */
	
	
	public DecisionLinesEvent (int numChoices) {
		this.numChoices = numChoices;
		
		lines = new ArrayList<Line>();
		allEdges = new ArrayList<Edge>();
		priorities = new String[numChoices];
	}
	
	public ArrayList<Edge> getAllEdges()
	{
		return allEdges;
	}
	
	/**
	 * Get the number of rounds in this decision lines event.
	 * @return
	 */
	
	public int getNumRounds()
	{
		return numRounds;
	}
	
	/**
	 * Set the amount of rounds in this decision lines event.
	 * @param rounds
	 */
	
	public void setNumRounds(int rounds)
	{
		numRounds = rounds;
	}
	
	/**
	 * Set the name of choice at the specified position.
	 * @param position
	 * @param name
	 * @return
	 */
	
	public boolean setChoice(int position, String name)
	{
		boolean okayFlag = true;
		
		for (int i = 0; i < lines.size(); i++)
		{
			if (i != position)
			{
				if (name.equals(this.lines.get(i).getChoiceName()))
					{
						okayFlag = false;
					}
			}
		}
		
		if (okayFlag)
		{
			this.lines.get(position).setChoiceName(name);
			return true;
		}
		
		return false;
	}
	
	/**
	 * Check to see if Edge e is valid based upon the parameters that 
	 * there are 7 pixels between it and any other edge, 
	 * and that it is between two neighboring edges.
	 * @param e
	 * @return
	 */
	
	public boolean isValidEdge(Edge e)
	{	

		if (numChoices * numRounds > allEdges.size())
		{
			if (e.right - e.left == 1)
			{
				for (Edge compEdge : lines.get(e.left).edges)
				{
					if (Math.abs(compEdge.getHeight() - e.getHeight()) < 7)
					{
						return false;
					}
				}
				for (Edge compEdge : lines.get(e.right).edges)
				{
					if (Math.abs(compEdge.getHeight() - e.getHeight()) < 7)
					{
						return false;
					}
				}
				
				return true;
	
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
	}
	
	/**
	 * Checks to see if edge e is valid, if so then it adds it to the Decision Lines Event
	 * @param e
	 * @return
	 */
	
	public boolean addEdge(Edge e)	
	{
		if (isValidEdge(e))
		{
			lines.get(e.left).edges.add(e);
			lines.get(e.right).edges.add(e);
			allEdges.add(e);
			return true;		
		}
		else
		{
			return false;
		}
	}
	
	/**
	 * Checks to see if n*m edges have been added. If true, then it's time to calculate the results!
	 * 
	 * @return
	 */
	public boolean isDone()
	{
		int numOfEdges = 0;
		
		for (int i = 0; i < allEdges.size(); i++)
		{
			numOfEdges += 1;
		}
		
		if (numChoices * numRounds == numOfEdges)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	
	/**
	 * Returns the prioritized choice names.
	 * 
	 * Basically it does a for loop through each line, creates a marker for which line we're
	 * currently in the middle of traversing (separate from the line we began at)
	 * then while the nextEdge() is not null, we keep doing this until there are no more edges
	 * and we're at the bottom of a line. Then it's stored in an array.
	 */
	
	public void prioritizedChoices()
	{
		
		int height = 0; 
		
		System.out.println("Prioritized Choices:");
		
		for (int l = 0; l < numChoices; l++)
		{	
			height = 0;
			int marker = lines.get(l).getPosition();
			
			while (lines.get(marker).nextEdge(height) != null)
			{
		
				
				Edge edge = lines.get(marker).nextEdge(height);
				
				if (edge.left == lines.get(marker).position)
				{
					height = lines.get(marker).nextEdge(height).getHeight();
					marker = edge.right;
				}
				else if (edge.right == lines.get(marker).position)
				{
					height = lines.get(marker).nextEdge(height).getHeight();
					marker = edge.left;
				}
						
			} 
			
			priorities[marker] = lines.get(l).getChoiceName();

		}

		
		for (int i = 0; i < numChoices; i++)
		{
			System.out.println(priorities[i]);
		}
		
	}
}
